﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Diagnostics;


namespace CommonTypes
{
    public interface IServer
    {
        String connect(String username,String ipPort);
        String disconnect(String username);
        String getClientRef(String username);
        int grantTicket();
        void sendTicketCounter(int port);
        void updateTicketCounter(int counter);
        void sendUsersList(int port);
        void updateUsersList(List<ClientInfo> clients);
        void setPrimary(int port);
        void setBackup(int port);
        void notifyWakeUp();
        String echo();
    }

    public interface IClient
    {
        //método que faz com que o cliente se ligue (conecte) ao servidor
        void connect(String username, String ipPort);

        void disconnect(String username);

        //método que permite, ao anfitrião, inicializar uma reserva
        void hostReservation(String description, List<String> guestList, List<int> slotList);

        //método para convidar um cliente (convidado) para uma reserva
        List<int> reservation(int reservationId, String gestUsername, String description, List<int> slotList);

        //método que permite visualizar o calendário de uma dado cliente
        SlotsToPuppet[] readCalendar();

        int book(int reservationId, String gestUsername, int slotToBook);

        bool commit(int reservationId, String guestUsername, int slotToCommit);

        void guestAbortReservation(int reservationId);
    }

    public interface IServersManager { 
        
       void connectReplica(String serverName, String ipPort);

       void disconnectReplica(String serverName);

       String activeServer();
    
    }

    public class SlotsToPuppet : MarshalByRefObject {
        private int number;
        private int reservationID;
        private String state;

        public SlotsToPuppet() { }

        public SlotsToPuppet(int number, String state, int reservationID)
        {
            this.number = number;
            this.state = state;
            this.reservationID = reservationID;
        }

        public int Number
        {
            get { return number; }
            set { number = value; }
        }

        public String State
        {
            get { return state; }
            set { state = value; }
        }

        public int ReservationID {
            get { return reservationID; }
            set { reservationID = value; }
        }
    }

    [Serializable]
    public class ClientInfo
    {
        private IClient clientRef;
        private String username;
        private String ipPort;
        private bool isOnline;
        private Process process;

        public ClientInfo(IClient clientRef, String username, String ipPort, Process process)
        {
            this.clientRef = clientRef;
            this.username = username;
            this.ipPort = ipPort;
            this.isOnline = true;
            this.process = process;
        }

        public IClient ClientRef
        {
            get { return clientRef; }
            set { clientRef = value; }
        }

        public String Username
        {
            get { return username; }
        }

        public String IpPort
        {
            get { return ipPort; }
            set { ipPort = value; }
        }

        public bool IsOnline
        {
            get { return isOnline; }
            set { isOnline = value; }
        }

        public Process ClientProcess {
            get { return process; }
            set { process = value; }
        }
    }

    public class ServerInfo
    {
        private String serverName;
        private IServer server;
        private String ipPort;
        private Process serverProcess;


        public ServerInfo(String serverName, IServer server, String ipPort, Process process)
        {
            this.serverName = serverName;
            this.server = server;
            this.ipPort = ipPort;
            this.serverProcess = process;
        }

        public IServer Server
        {
            get { return server; }
            set { server = value; }
        }

        public String ServerName
        {
            get { return serverName; }
        }

        public String IpPort
        {
            get { return ipPort; }
            set { ipPort = value; }
        }

        public Process ServerProcess
        {
            get { return serverProcess; }
        }
    }
}
